import { toRef, ref, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useExamStore } from '@/stores/modules/exam-student'
import { localURL } from '@/utils/request-student'
import { useUserStore } from '@/stores/modules/user-student'


/**
 * 考试监控相关功能
 * @param {Object} settings 监控设置参数
 * @returns {Object} 监控相关方法
 */
export function useExamMonitor(settings) {
  const router = useRouter()
  const examStore = useExamStore()
  const userStore = useUserStore()
  const route = useRoute()

  // WebSocket连接
  const socket = ref(null)
  // 连接状态
  const isConnected = ref(false)
  // 重试次数
  const retryCount = ref(0)
  // 最大重试次数
  const MAX_RETRY = 3

  /**
   * 初始化WebSocket连接
   */
  const initWebSocket = () => {
    if (socket.value) {
        console.log("已存在")
        return
    }
    try {
      // TODO: WebSocket地址应从配置获取
      const httpURL = new URL(localURL);
      const wsUrl = `ws://${httpURL.host}/ws/monitor/${userStore.userInfo.id}`
      socket.value = new WebSocket(wsUrl)

      socket.value.onopen = () => {
        isConnected.value = true
        retryCount.value = 0
        console.log('WebSocket连接已建立')
      }

      socket.value.onmessage = (event) => {
        const data = JSON.parse(event.data)
        if (data.type === 'violationResponse') {
          handleViolationResponse(data.payload)
        }
      }

      socket.value.onclose = () => {
        isConnected.value = false
        console.log('WebSocket连接已关闭')
        // 尝试重新连接
        if (retryCount.value < MAX_RETRY) {
          retryCount.value++
          setTimeout(initWebSocket, 3000)
        }
      }

      socket.value.onerror = (error) => {
        console.error('WebSocket错误:', error)
      }
    } catch (error) {
      console.error('WebSocket初始化失败:', error)
    }
  }

  /**
   * 处理违规响应
   * @param {Object} payload 响应数据
   */
  const handleViolationResponse = (payload) => {
    if (payload.forceSubmit) {
      handleForceSubmit(payload.reason || '违规次数过多')
    }
  }

  /**
   * 通过WebSocket发送违规记录
   * @param {String} type 违规类型
   * @param {String} description 违规描述
   * @returns {Promise<Boolean>} 是否强制提交
   */
  const recordViolationViaWS = async (type, description) => {
    if (!isConnected.value) {
      console.warn('WebSocket未连接，尝试重新连接')
      initWebSocket()
      return false
    }

    return new Promise((resolve) => {
      const message = {
        type: 'violation',
        payload: {
          violationType: type,
          description,
          studentPaperId: examStore.currentExam.studentPaperId,
          studentId: userStore.userInfo.id
        }
      }

      socket.value.send(JSON.stringify(message))

      // 设置超时处理
      const timeout = setTimeout(() => {
        resolve(false)
      }, 5000)

      // 临时监听响应
      const tempListener = (event) => {
        const data = JSON.parse(event.data)
        if (data.type === 'violationResponse') {
          clearTimeout(timeout)
          socket.value.removeEventListener('message', tempListener)
          resolve(data.payload.forceSubmit)
        }
      }

      socket.value.addEventListener('message', tempListener)
    })
  }
  // 违规警告次数
  const warningCount = toRef(examStore, 'violationCount');
  // 最大警告次数（超过将强制提交）
  const maxWarnings = ref(settings.maxWarnings || 5)

  console.log('警告次数' + warningCount.value + 'max' + maxWarnings.value)
  /**
   * 切屏检测
   * 监听页面可见性变化，记录切屏违规行为
   */
  const handleVisibilityChange = async () => {
    // 仅当页面不可见时触发（切换到其他窗口或标签页）
    if (!document.hidden) return

    // 如果不允许切屏
    if (!settings.allowSwitchScreen) {
      // 记录切屏违规
      const shouldForceSubmit = await recordViolationViaWS('switchScreen', '切换到其他窗口')

      warningCount.value++

      // 是否应该强制提交
      if (shouldForceSubmit || warningCount.value >= maxWarnings.value) {
        await handleForceSubmit('切屏次数过多')
      } else {
        ElMessage.warning(`切换窗口将被记录为违规行为，这是第 ${warningCount.value}/${maxWarnings.value} 次警告`)
      }
    }
    // 如果限制切屏次数
    else if (settings.maxSwitchCount) {
      // 记录切屏违规
      const shouldForceSubmit = await recordViolationViaWS('switchScreen', '切换到其他窗口')

      // 计算剩余可切屏次数
      const remaining = settings.maxSwitchCount - examStore.switchScreenCount

      // 是否应该强制提交
      if (shouldForceSubmit || remaining <= 0) {
        await handleForceSubmit('切屏次数已用完')
      } else {
        ElMessage.warning(`您还可以切换窗口 ${remaining} 次`)
      }
    }
  }

  /**
   * 全屏控制
   * 监听全屏状态变化，记录退出全屏违规行为
   */
  const handleFullscreenChange = async () => {
    const isFullscreen = !!document.fullscreenElement
    examStore.setFullscreen(isFullscreen)

    // 如果要求全屏且当前不是全屏状态
    if (settings.requireFullscreen && !isFullscreen) {
      // 记录退出全屏违规
      const shouldForceSubmit = await recordViolationViaWS('exitFullscreen', '退出全屏模式')

      warningCount.value++

      // 是否应该强制提交
      if (shouldForceSubmit || warningCount.value >= maxWarnings.value) {
        await handleForceSubmit('退出全屏次数过多')
      } else {
        ElMessage.warning(`请保持全屏状态，这是第 ${warningCount.value}/${maxWarnings.value} 次警告`)
        // 自动请求回到全屏
        requestFullscreen()
      }
    }
  }

  /**
   * 复制粘贴限制
   * 禁止复制粘贴，记录违规行为
   * @param {Event} event 事件对象
   */
  const handleCopyPaste = async (event) => {
    // 如果不允许复制粘贴
    if (!settings.allowCopyPaste) {
      // 阻止默认行为
      event.preventDefault()

      // 记录复制粘贴违规
      const shouldForceSubmit = await recordViolationViaWS('copyPaste',
        `${event.type === 'copy' ? '复制' : '粘贴'}操作`)

      warningCount.value++

      // 是否应该强制提交
      if (shouldForceSubmit || warningCount.value >= maxWarnings.value) {
        await handleForceSubmit('复制粘贴违规次数过多')
      } else {
        ElMessage.warning(`禁止复制粘贴，这是第 ${warningCount.value}/${maxWarnings.value} 次警告`)
      }
    }
  }

  /**
   * 监控键盘快捷键
   * 禁止特定键盘快捷键（如打印、开发者工具等）
   * @param {KeyboardEvent} event 键盘事件
   */
  const handleKeyDown = async (event) => {
    // 监控常见的违规快捷键
    const blockedKeys = [
      // 禁止 F12 (开发者工具)
      { key: 'F12', ctrl: false, alt: false, shift: false },
      // 禁止 Ctrl+Shift+I (开发者工具)
      { key: 'I', ctrl: true, alt: false, shift: true },
      // 禁止 Ctrl+P (打印)
      { key: 'P', ctrl: true, alt: false, shift: false }
    ]

    // 检查是否匹配被禁止的快捷键
    const isBlocked = blockedKeys.some(k =>
      event.key === k.key &&
      event.ctrlKey === k.ctrl &&
      event.altKey === k.alt &&
      event.shiftKey === k.shift
    )

    if (isBlocked) {
      // 阻止默认行为
      event.preventDefault()

      // 记录键盘快捷键违规
      const shouldForceSubmit = await recordViolationViaWS('keyboardShortcut',
        `使用快捷键: ${event.ctrlKey ? 'Ctrl+' : ''}${event.altKey ? 'Alt+' : ''}${event.shiftKey ? 'Shift+' : ''}${event.key}`)

      warningCount.value++

      // 是否应该强制提交
      if (shouldForceSubmit || warningCount.value >= maxWarnings.value) {
        await handleForceSubmit('违规使用快捷键次数过多')
      } else {
        ElMessage.warning(`禁止使用此快捷键，这是第 ${warningCount.value}/${maxWarnings.value} 次警告`)
      }
    }
  }

  /**
   * 强制提交
   * 违规次数过多时，强制提交试卷
   * @param {String} reason 强制提交的原因
   */
  const handleForceSubmit = async (reason = '违规次数过多') => {
    await ElMessageBox.alert(
      `由于${reason}，系统将自动提交您的试卷`,
      '警告',
      {
        type: 'warning',
        showClose: false,
        confirmButtonText: '确定'
      }
    )

    // 同步答案
    await examStore.syncAnswers()

    // 跳转到提交页面
    // router.push(`/exam/${examStore.currentExam.id}/submit?force=true&studentPaperId=${examStore.currentExam.studentPaperId}`)
    router.push('/exam/list')
  }

  /**
   * 请求全屏
   */
  const requestFullscreen = async () => {
    if (!settings.requireFullscreen) return
      try {
        // 先通过用户交互触发弹窗
        await ElMessageBox.confirm(
          '为保障考试公平性，请进入全屏模式进行考试',
          '全屏提示',
          {
            confirmButtonText: '进入全屏',
            cancelButtonText: '取消考试',
            type: 'warning',
            closeOnClickModal: false, // 禁止点击蒙层关闭
            closeOnPressEscape: false, // 禁止 ESC 关闭
            showClose: false // 隐藏关闭按钮
          }
        )

        // 用户确认后尝试全屏
        await doFullscreen()

      } catch (error) {
        if (error === 'cancel' || error === 'close') {
          // 用户主动取消
          ElMessage.warning('您已取消进入全屏，考试无法继续！')

          router.push(`/exam/${route.params.id}`)
        } else {
          // 全屏失败
          ElMessage.error('全屏模式启动失败，请检查浏览器设置')
        }
      }
  }

  const doFullscreen = async () => {
    try {
      const element = document.documentElement
      if (element.requestFullscreen) {
        await element.requestFullscreen()
      } else if (element.mozRequestFullScreen) { // Firefox
        await element.mozRequestFullScreen()
      } else if (element.webkitRequestFullscreen) { // Chrome/Safari
        await element.webkitRequestFullscreen()
      } else if (element.msRequestFullscreen) { // IE/Edge
        await element.msRequestFullscreen()
      }
    } catch (error) {
      console.error('进入全屏失败:', error)
      ElMessage.error('无法进入全屏模式，请检查浏览器设置')
    }
  }

    /**
     * 初始化监控
     */
    const initMonitor = async () => {
      await requestFullscreen()
    }

  

  onMounted(() => {
    // 初始化WebSocket连接
    initWebSocket()
    
    // 添加监听器
    document.addEventListener('visibilitychange', handleVisibilityChange)
    document.addEventListener('fullscreenchange', handleFullscreenChange)
    document.addEventListener('copy', handleCopyPaste)
    document.addEventListener('paste', handleCopyPaste)
    document.addEventListener('keydown', handleKeyDown)

    // 初始化监控
    // initMonitor()
  })

  onUnmounted(() => {
    // 关闭WebSocket连接
    if (socket.value) {
      socket.value.close()
      socket.value = null
    }
    
    // 移除监听器
    document.removeEventListener('visibilitychange', handleVisibilityChange)
    document.removeEventListener('fullscreenchange', handleFullscreenChange)
    document.removeEventListener('copy', handleCopyPaste)
    document.removeEventListener('paste', handleCopyPaste)
    document.removeEventListener('keydown', handleKeyDown)

    // 退出全屏状态
    if (document.fullscreenElement) {
      document.exitFullscreen().catch(err => console.error('退出全屏失败:', err))
    }
  })

  return {
    requestFullscreen,
    warningCount,
    maxWarnings,
    initMonitor
  }
}